#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<iostream>
#include<iomanip>

int num[4][4] = { 0 };
int height = 400;
int width = 400;
int bianchang = 100;
char moveDirection;
int x, y;
int k;
int flag;//用来判断是否要放置新数字(flag==1则放置新数字）
int i, j;
int score = 0;
void move_left()
{
	for (i = 0; i < 4; i++)
	{
		for (j = 1, k = 0; j < 4; j++)
		{

			if (num[i][j] > 0) //如果路径上存在数字
			{
				if (num[i][k] == num[i][j]) //两方块数字相同
				{
					num[i][k] *= 2;//融合后数字*2
					k++;
					score = score + 2 * num[i][j];//分数累积
					num[i][j] = 0;//清除碰撞方块
					flag = 1;//
				}
				else if (num[i][k] == 0) //路径上数字为空
				{
					num[i][k] = num[i][j];//取代空方块
					num[i][j] = 0;//原方块清空
					flag = 1;//判断可以新增一个随机方块
				}
				else
				{
					num[i][k + 1] = num[i][j];//不相邻的相同方块
					if ((k + 1) != j)
					{
						num[i][j] = 0;//原方块清空
						flag = 1;//判断可以新增一个随机方块
					}
					k++;
				}
			}
		}
	}
}

void move_right()
{
	for (i = 0; i < 4; i++)
	{
		for (j = 2, k = 3; j >= 0; j--)
		{

			if (num[i][j] > 0) //如果路径上存在数字
			{
				if (num[i][k] == num[i][j]) //两方块数字相同
				{
					num[i][k] *= 2;//融合后数字*2
					k++;
					score = score + 2 * num[i][j];//分数累积
					num[i][j] = 0;//清除碰撞方块
					flag = 1;//
				}
				else if (num[i][k] == 0) //路径上数字为空
				{
					num[i][k] = num[i][j];//取代空方块
					num[i][j] = 0;//原方块清空
					flag = 1;//判断可以新增一个随机方块
				}
				else
				{
					num[i][k - 1] = num[i][j];//不相邻的相同方块
					if ((k - 1) != j)
					{
						num[i][j] = 0;//原方块清空
						flag = 1;//判断可以新增一个随机方块
					}
					k--;
				}
			}
		}
	}
}

void move_up()
{
	for (i = 0; i < 4; i++)
	{
		for (j = 1, k = 0; j < 4; j++)
		{

			if (num[j][i] > 0) //如果路径上存在数字
			{
				if (num[k][i] == num[j][i]) //两方块数字相同
				{
					num[k][i] *= 2;//融合后数字*2
					k++;
					score = score + 2 * num[i][j];//分数累积
					num[j][i] = 0;//清除碰撞方块
					flag = 1;//
				}
				else if (num[k][i] == 0) //路径上数字为空
				{
					num[k][i] = num[j][i];//取代空方块
					num[j][i] = 0;//原方块清空
					flag = 1;//判断可以新增一个随机方块
				}
				else
				{
					num[k+1][i] = num[j][i];//不相邻的相同方块
					if ((k + 1) != j)
					{
						num[j][i] = 0;//原方块清空
						flag = 1;//判断可以新增一个随机方块
					}
					k++;
				}
			}
		}
	}
}

void move_down()
{
	for (i = 0; i < 4; i++)
	{
		for (j = 2, k = 3; j >= 0; j--)
		{

			if (num[j][i] > 0) //如果路径上存在数字
			{
				if (num[k][i] == num[j][i]) //两方块数字相同
				{
					num[k][i] *= 2;//融合后数字*2
					k++;
					score = score + 2 * num[i][j];//分数累积
					num[j][i] = 0;//清除碰撞方块
					flag = 1;//
				}
				else if (num[k][i] == 0) //路径上数字为空
				{
					num[k][i] = num[j][i];//取代空方块
					num[j][i] = 0;//原方块清空
					flag = 1;//判断可以新增一个随机方块
				}
				else
				{
					num[k - 1][i] = num[j][i];//不相邻的相同方块
					if ((k - 1) != j)
					{
						num[j][i] = 0;//原方块清空
						flag = 1;//判断可以新增一个随机方块
					}
					k--;
				}
			}
		}
	}
}
int ln2(int a)
{
	int zhishu = 0;
	while (a % 2 == 0)
	{
		zhishu++;
		a = a / 2;
	}
	return zhishu;
}//用于衡量数字的大小
void renew_2()
{
	while (1)//更新一个新的2
	{
		x = rand() % 4; y = rand() % 4;
		if (num[x][y] == 0)
		{
			num[x][y] = 2;
			break;
		}
	}
}
void startup()
{
	initgraph(height, width);//输出对话框
	cleardevice();//清屏
	x = rand() % 4; y = rand() % 4;//初始化一个2
	num[x][y] = 2;
	renew_2();//再初始化一个2
}
void move()
{
	int i, j;
	switch (moveDirection)//根据指令移动数字
	{
	case 'w':
		move_up();
		break;
	case 's'://向下
		move_down();
		break;
	case 'd'://向右
		move_right();
		break;
	case 'a'://向左
		move_left();
		break;
	}
	if (flag)
		renew_2();
}
void show()
{
	BeginBatchDraw();
	int i, j;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if (num[i][j] == 0)
			{
				setfillcolor(HSVtoRGB(0, 0.1, 0.1));
				fillrectangle(i * bianchang, j * bianchang, (i + 1) * bianchang, (j + 1) * bianchang);
			}
			else
			{
				setfillcolor(HSVtoRGB(ln2(num[i][j]) * 20, 0.9, 0.3));
				fillrectangle(i * bianchang, j * bianchang, (i + 1) * bianchang, (j + 1) * bianchang);
			}
		}
	}//填充方格

	settextcolor(WHITE);
	settextstyle(bianchang, bianchang, _T("宋体"));
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if (num[i][j] != 0)

			{
				TCHAR s[5];
				_stprintf_s(s, _T("%d"), num[i][j]);
				outtextxy(100 * j, 100 * i, s);
			}
		}
	}//输出数字
	FlushBatchDraw();

}//游戏绘制
int judge()//判断游戏是否失败
{
	int i, j;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
			if (num[i][j] == 0)
				return 1;
	}
	return 0;
}
void updatewith()//获取键盘信息
{
	if (_kbhit && judge)
	{
		moveDirection = _getch();

	}
}

int main()
{
	startup();
	while (1)
	{
		show();
		updatewith();
		move();


	}
}




